package cn.xd.itstack.springframework.beans.factory.support;

import cn.xd.itstack.springframework.beans.BeansException;
import cn.xd.itstack.springframework.beans.factory.FactoryBean;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Classname FactoryBeanRegistrySupport
 * @Description TODO
 * @Date 2022/5/27 下午5:48
 * @Created by lvxiaodong
 */
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

    /**
     * 属性：FactoryBean缓存容器
     * 方法1：根据beanName从缓存中获取对象
     * 方法2：从FactoryBean中获取对象
     */

    private Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>();


    protected Object getCacheObjectFromFactoryBean(String beanName) {
        Object object = factoryBeanObjectCache.get(beanName);
        return (object != NULL_OBJECT ? object : null);
    }


    protected Object getObjectFromFactoryBean(FactoryBean factoryBean, String beanName) {
        if (factoryBean.isSingleton()) {
            Object object = factoryBeanObjectCache.get(beanName);
            if (object == null) {
                object = doGetObjectFromFactoryBean(factoryBean, beanName);
                this.factoryBeanObjectCache.put(beanName, object);
            }
            return (object != NULL_OBJECT ? object : null);
        } else {
            return doGetObjectFromFactoryBean(factoryBean, beanName);
        }
    }

    private Object doGetObjectFromFactoryBean(final FactoryBean factoryBean, final String beanName) {
        try {
            Object object=  factoryBean.getObject();
            return object;
        } catch (Exception e) {
            throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
        }
    }

}
